home *** CD-ROM | disk | FTP | other *** search
/ Aminet 3 / Aminet 3 - July 1994.iso / Aminet / util / misc / Pubby101.lha / Pubby.c next >
Encoding:
C/C++ Source or Header  |  1994-03-23  |  11.2 KB  |  320 lines

  1. /* This is a Public Screen program I'm writing.
  2.    Compile with:
  3.     dcc pubby.c -o pubby -l reqtoolss.lib
  4.    Use the -r option to make it residentiable. */
  5.  
  6. #define PUBBYVERSION    "1.01"
  7.  
  8. #include <libraries/reqtools.h>
  9. #include <proto/reqtools.h>
  10. #include <libraries/gadtools.h>
  11. #include <clib/gadtools_protos.h>
  12.  
  13. /* Need this because OpenScreenTags is prototyped here. */
  14. #include <clib/intuition_protos.h>
  15.  
  16. /* I use this to indicate the version number of Pubby. */
  17. static const char *Ver ="$VER: Pubby 1.0";
  18.  
  19. struct ReqToolsBase *ReqToolsBase;
  20.  
  21. /* This is a structure that holds the info for my About... requestor.
  22.    EasyRequest() will be using this to build the requester. */
  23. struct EasyStruct myeasystruct=
  24. {
  25.     sizeof(struct EasyStruct),
  26.     0,
  27.     "About my program",
  28.     "Pubby v%s\nby Todd Courtnage\nE-mail: courtn@cs.uregina.ca",
  29.     "Okey-dokey!",
  30. };
  31.  
  32.  
  33. /* This is a structure that tells GadTools what my
  34.    menu will look like.  With ADOS 2.04, it actually seems
  35.    quite easy to do! */
  36. struct NewMenu mynewmenu[]=
  37. {
  38.     { NM_TITLE, "Project",0,0,0,0,},
  39.     {   NM_ITEM, "About...","!",0,0,0,},
  40.     {   NM_ITEM, "Quit","Q",0,0,0,},
  41.  
  42.     { NM_END,NULL,0,0,0,0,},
  43. };
  44.  
  45. typedef struct WBStartup    WBS;
  46. short IconSaveOpt;
  47.  
  48. /* This code was taken from the source for DME.  It is for WB
  49.    startup.  There is no explanation in the docs on how wbmain
  50.    works.  Can someone explain this to me???
  51.    BTW, if you try to start Pubby from the WB after it's already
  52.    running, nothing will happen.  It just won't run. */
  53. int wbmain(wbs)
  54. WBS *wbs;
  55. {
  56.     IconSaveOpt=1;
  57.     return(main(0,(char **)wbs));
  58. }
  59.  
  60.  
  61. main(int argc, char *argv[])
  62. {
  63.  
  64.     struct  Screen *my_screen;
  65.     struct Window *my_window;
  66.     struct rtScreenModeRequester *screenmodereq;
  67.     struct Screen *pubby_screen;
  68.  
  69.     /* This is a pointer to a structure that holds the visual info
  70.        of the screen I want to put the menu on.  GadTools needs it
  71.        so it knows how to set the menus up so they look pretty. */
  72.     APTR *my_VisualInfo;
  73.  
  74.     /* This is a structure that holds the structure of the menus. */
  75.     struct Menu *menuStrip;
  76.  
  77.     /* Don't know what this is for.  I got this from the RKRM: Libraries
  78.        manual. */
  79.     UWORD pens[]={~0};
  80.  
  81.     /* First things first.  Find out if a copy of Pubby is already running.
  82.        What I do is try to lock a public screen with the LockPubScreen()
  83.        function.  I'll pass it a parameter of Pubby, since that's the name
  84.        of my public screen.  If it returns NULL, then there is not a version
  85.        of Pubby already running. */
  86.     pubby_screen=LockPubScreen("Pubby");
  87.     if(pubby_screen!=NULL)
  88.     {
  89.         printf("A version of Pubby is already running.\n");
  90.         UnlockPubScreen(NULL,pubby_screen);
  91.         exit(0);
  92.     }
  93.  
  94.  
  95.     /* Let's parse the command line arguments.  Only a ? will be
  96.        recognized right now.  I don't understand this!  argv is a
  97.        one-dimensional array, yet I've looked at other peoples code,
  98.        and they do this to see if the first argument.  If I try
  99.        if(argv[1]=='?')
  100.        it doesn't work.  And
  101.        if(argv[1]=="?")
  102.        doesn't work either.  Can someone explain this to me?
  103.        PS:  I got this from the source code to Flying Toasters
  104.        screen blanker, but I've seen similar things done in other
  105.        programs as well. */
  106.     if(argv[1][0]=='?')
  107.     {
  108.         printf("Pubby v%s, by Todd Courtnage (e-mail: courtn@cs.uregina.ca)\n",PUBBYVERSION);
  109.         printf("This program opens up a public screen of any size/shape/color/etc.\n");
  110.         printf("upon which any program which has the option of starting up on a public\n");
  111.         printf("screen can use this screen.\nPublic screen name: Pubby (names are case sensitive!)\n");
  112.         exit(0);
  113.     }
  114.  
  115.     /* Open up the reqtools.library.  Library version must be
  116.        v38 or greater because I want to use the screenmode
  117.        requestor. */
  118.     ReqToolsBase=(struct Library *)OpenLibrary("reqtools.library",38);
  119.     if(ReqToolsBase==NULL)
  120.     {
  121.        printf("Couldn't open reqtools.library\n");
  122.        exit(0);
  123.     }
  124.     else if (ReqToolsBase==0)
  125.     {
  126.         printf("Your reqtools.library isn't of a high enough version.\n");
  127.         printf("Get a new version and try again.\n");
  128.     }
  129.  
  130.     /* Now, I'm going to try and open up the screen mode requestor.
  131.        First I have to set up the requestor structure using
  132.        rtAllocRequestA(). */
  133.     if(!(screenmodereq=rtAllocRequestA(RT_SCREENMODEREQ,NULL)))
  134.     {
  135.        printf("For some reason, I couldn't allocate the screenmodereq structure.\n");
  136.        CloseLibrary(ReqToolsBase);
  137.        exit(0);
  138.     }
  139.  
  140.     /* This pops open the screen mode requester in the center of the screen.
  141.        OK, this works!  In order to use rtScreenModeRequest (the one with tags),
  142.        I have to tell DICE to include reqtoolss.lib when I compile it.
  143.        Add "-l reqtoolss.lib" to the compiler command. */
  144.     rtScreenModeRequest(screenmodereq,"Pick a display mode",
  145.                         RT_ReqPos,REQPOS_CENTERSCR,
  146.                         RTSC_Flags,SCREQF_DEPTHGAD|SCREQF_OVERSCANGAD|SCREQF_AUTOSCROLLGAD|SCREQF_SIZEGADS|
  147.                         SCREQF_NONSTDMODES
  148.                         ,TAG_DONE);
  149.  
  150.  
  151.     /* I have to free the requester structure now that I'm done with it.
  152.        This is why I was losing some memory every time the program was run.
  153.        (112 bytes was being lost, to be exact.) */
  154.     rtFreeRequest(screenmodereq);
  155.  
  156.     /* screenmodereq->DisplayID contains which display the user picked from the requester.
  157.        (i.e. PAL:High Res, NTSC:Low Res Laced, etc) */
  158.  
  159.  
  160.     /* Now, open up the screen.  Use screenmodereq->DisplayID as the type of display the
  161.        user wants.  Note: Autoscrolling will not work unless there is a windows in the screen! */
  162.     my_screen=OpenScreenTags(NULL,SA_Depth,screenmodereq->DisplayDepth,SA_DisplayID,screenmodereq->DisplayID,
  163.                              SA_Width,screenmodereq->DisplayWidth,SA_Height,screenmodereq->DisplayHeight,
  164.                              SA_Overscan,screenmodereq->OverscanType,SA_AutoScroll,screenmodereq->AutoScroll
  165.                              ,SA_Title,"Pubby",SA_Pens,(ULONG)pens,SA_PubName,"Pubby",
  166.                              TAG_DONE);
  167.  
  168.     if(my_screen==FALSE)
  169.     {
  170.         printf("You cancelled the requeser!!!  Shame on you!\n");
  171.         CloseLibrary(ReqToolsBase);
  172.         exit(0);
  173.     }
  174.     else if(my_screen==NULL)
  175.     {
  176.         printf("Can't open screen.\n");
  177.         CloseLibrary(ReqToolsBase);
  178.         exit(0);
  179.     }
  180.  
  181.     PubScreenStatus(my_screen,NULL);
  182.     my_window=OpenWindowTags(NULL,WA_CustomScreen,my_screen,
  183.                             WA_Backdrop,TRUE,
  184.                             WA_Borderless,TRUE,
  185.                             WA_IDCMP,IDCMP_MENUPICK
  186.                             );
  187.     if(my_window==FALSE)
  188.     {
  189.         printf("Couldn't open up the backdrop window.\n");
  190.         CloseScreen(my_screen);
  191.         CloseLibrary(ReqToolsBase);
  192.     }
  193.  
  194.  
  195.  
  196.     /* Get visual info of my screen. */
  197.     my_VisualInfo = GetVisualInfo(my_screen, TAG_END);
  198.     if(my_VisualInfo==NULL)
  199.     {
  200.         printf("GetVisualInfo() failed.  Have no idea why!\n");
  201.         CloseScreen(my_screen);
  202.         CloseLibrary (ReqToolsBase);
  203.         exit(0);
  204.     }
  205.  
  206.     /* This sets up the menu structure for me automatically. */
  207.     menuStrip = CreateMenus(mynewmenu, TAG_END);
  208.     if(menuStrip==NULL)
  209.     {
  210.         printf("Couldn't create the menu structure (i.e. CreateMenus() failed.\n");
  211.         FreeVisualInfo(my_VisualInfo);
  212.         CloseScreen(my_screen);
  213.         CloseLibrary (ReqToolsBase);
  214.         exit(0);
  215.     }
  216.  
  217.     /* Now, I have to call LayoutMenus() to layout the menus based on the
  218.        info I got from the GetVisualInfo() call.  LayoutMenus() returns
  219.        either TRUE or FALSE, that's why I'm putting it directly in the
  220.        if() structure. */
  221.     if(!(LayoutMenus(menuStrip,my_VisualInfo,TAG_END)))
  222.     {
  223.         printf("Couldn't layout the menus.\n");
  224.         FreeMenus(menuStrip);    /* Free memory allocated by CreateMenus. */
  225.         FreeVisualInfo(my_VisualInfo);
  226.         CloseScreen(my_screen);
  227.         CloseLibrary (ReqToolsBase);
  228.         exit(0);
  229.     }
  230.  
  231.     /* Now, I physically open up the menu.  Always returns TRUE.*/
  232.     SetMenuStrip(my_window,menuStrip);
  233.  
  234.     /*Delay(500L);*/
  235.  
  236.     /* Now that the screen is opened, just wait for the user to select
  237.        About or Quit from the menu. */
  238.     wait_for_menu(my_window,menuStrip);
  239.  
  240.     ClearMenuStrip(my_window);
  241.     FreeMenus(menuStrip);
  242.     FreeVisualInfo(my_VisualInfo);
  243.     CloseWindow(my_window);
  244.     CloseScreen(my_screen);
  245.     CloseLibrary (ReqToolsBase);
  246.  
  247.     exit(0);
  248. }
  249.  
  250. /* This function waits for the user to select a menu item from the screen, then
  251.    acts accordingly.  I don't fully understand what's going on in here yet, I more
  252.    or less just took it from the RKRM manuals (gadtoolsmenu.c example). */
  253.  
  254. wait_for_menu(struct Window *my_window, struct Menu *menuStrip)
  255. {
  256.     struct IntuiMessage *msg;
  257.     SHORT done;
  258.     UWORD menuNumber;
  259.     UWORD menuNum;
  260.     UWORD itemNum;
  261.     UWORD subNum;
  262.     struct MenuItem *item;
  263.  
  264.     done=FALSE;
  265.     while (FALSE==done)
  266.     {
  267.         /* This causes my program to wait until the signal bit of the UserPort structure
  268.            of the window structure get's changed, to indicate a IDCMP event took place.
  269.            i.e. the window (pointed to by win) is a structure, and one of the elements of
  270.            that structure is called UserPort, which is in itself a structure, which has
  271.            an element called mp_SigBit, which is a signal bit to indicate an IDCMP event
  272.            took place. */
  273.         Wait(1L << my_window->UserPort->mp_SigBit);
  274.  
  275.         while((FALSE==done) && (NULL!=(msg=(struct IntuiMessage *)GetMsg(my_window->UserPort))))
  276.         {
  277.             switch (msg->Class)
  278.             {
  279.                 case IDCMP_MENUPICK:
  280.                     menuNumber=msg->Code;
  281.                     while((menuNumber!=MENUNULL)&&(!done))
  282.                     {
  283.                         item=ItemAddress(menuStrip,menuNumber);
  284.  
  285.                         /* Extracts which item of which menu was selected.
  286.                            Starts counting at 0. */
  287.                         menuNum=MENUNUM(menuNumber);
  288.                         itemNum=ITEMNUM(menuNumber);
  289.                         subNum=SUBNUM(menuNumber);
  290.  
  291.                         /* If the selection was the first menu (start counting at 0)
  292.                            and the item selected was the 2nd one, then the user
  293.                            selected quit, so quit the program. */
  294.                         if((menuNum==0)&&(itemNum==1))
  295.                             done=TRUE;
  296.  
  297.                         /* If user selected the About... menu item, then call a function
  298.                            to show my name. :-) */
  299.                         if((menuNum==0)&&(itemNum==0))
  300.                             showabout(my_window);
  301.  
  302.                         /* Get the next menu item selected, returns MENUNULL if
  303.                            no more selections. */
  304.                         menuNumber=item->NextSelect;
  305.                     }
  306.                 break;  /* break out of the switch structure */
  307.             }
  308.             ReplyMsg((struct Message *)msg);
  309.         }
  310.     }
  311. }
  312.  
  313. /* This procedure get's executed whenever the user select the About... menu
  314.    item.  EasyRequest() simply calls a requester. */
  315. showabout(struct Window *my_window)
  316. {
  317.     LONG answer;
  318.  
  319.     answer=EasyRequest(my_window,&myeasystruct,NULL,PUBBYVERSION);
  320. }